# encoding: utf-8

import requests,json,time,os
'''
通过调用api来获取txt数据
'''
SERVER_IP='meteo.awit.net.cn'
SERVER_PORT=10280

SERVER_ADD='http://{0}:{1}/GuiYang_weather_BS'.format(SERVER_IP,SERVER_PORT)
#登录获取路线URL
FETCH_ROADS='{0}/login.do?doLogin&userName={1}&passWord={2}'.format(SERVER_ADD,'demo2','123456')
#根据路线id获取所有预报点URL
FETCH_FORCAST='{0}/weatherData.do?getActivedForcast'.format(SERVER_ADD)
#本地化测试
# SERVER_IP='localhost'
# SERVER_PORT=8080
# SERVER_ADD='http://{0}:{1}/GuiYang_weather_BS'.format(SERVER_IP,SERVER_PORT)
#通知服务器开始持久化数据
INSERT_FORCAST_DATA='{0}/rdft.do?doRdft'.format(SERVER_ADD)

#txt存放的路径
TXT_PATH='/mnt/ftp/meteoftp/{0}'
# TXT_PATH='F:/Share/awitNcFile/{0}'
TXT_NAME='{0}_{1}_{2}_api.txt'
#下载的配置
DATA_CONFIG={
    'hefei':{
        'name':'合肥',
        'api':'http://183.57.41.102/wrf_lusuwan/nc/china_lusuwan_api.php?lon={0}&lat={1}&model={2}&domain={3}',
        'plan':['A'],
        'nc':'d1',
        'update':True,
        'rid':None
    },
    #http://113.106.88.29/wrf_yuqian/nc/china_yuqian_api.php?lon=105.512&lat=27.489&model=A&domain=d1
    'chongqing2':{
        'name':'重庆涪陵',
        'api':'http://113.106.88.29/wrf_yuqian/nc/china_yuqian_api.php?lon={0}&lat={1}&model={2}&domain={3}',
        'plan':['A'],
        'nc':'d1',
        'update':False,
        'rid':None
    },
    'guiyang':{
        'name':'贵阳',
        'api':'http://113.106.88.29/wrf_yuqian/nc/china_yuqian_api.php?lon={0}&lat={1}&model={2}&domain={3}',
        'plan':['A'],
        'nc':'d1',
        'update':False,
        'rid':None
    },
    'zunyi':{
        'name':'遵义',
        'api':'http://113.106.88.29/wrf_yuqian/nc/china_yuqian_api.php?lon={0}&lat={1}&model={2}&domain={3}',
        'plan':['A'],
        'nc':'d1',
        'update':False,
        'rid':None
    },
    'chongqing':{
        'name':'重庆',
        'api':'http://113.106.88.29/wrf_yuqian/nc/china_yuqian_api.php?lon={0}&lat={1}&model={2}&domain={3}',
        'plan':['A'],
        'nc':'d1',
        'update':False,
        'rid':None
    }
}


#添加日志
def addLog(logInfo):
    print(logInfo)

def getTimeStr():
    return time.strftime("%Y%m%d%H", time.localtime())

#判断是否7天前的旧数据
def isOldFile(t,length):
    mktime = time.mktime(time.strptime(t, "%Y%m%d%H"))
    return (time.time()-mktime)>length

#获取所有路线结果
def getAllRoad():
    result = requests.post(FETCH_ROADS)
    if result.status_code==200:
        return json.loads(result.text)['obj']['roads']
    else:
        return None

#获取路线对应预报点
def getAllForcast(roadId):
    result = requests.get(FETCH_FORCAST + '&rid={0}'.format(roadId))
    if result.status_code==200:
        return json.loads(result.text)['obj']['data']
    else:
        return None

#从api里获取数据
def getDataFromApi(url,roadcode):
    result = requests.get(url)
    if result.status_code==200:
        apiData = json.loads(result.text)
        return apiData
    else:
        addLog('[{0}]：{1} 未获取数据'.format(roadcode,url))
        return None

#是否需要更新数据的判断-并且删除7天前旧数据
def isUpdated(apiData,roadCode):
    if len(apiData) > 0:
        txtPath = TXT_PATH.format(roadCode)
        # 验证数据是否更新
        if os.path.exists(txtPath) is False:
            os.makedirs(txtPath)
            return True
        dealData=True
        stime = apiData[0]['time']  # 数据的开始时间
        for f in os.listdir(txtPath):
            if f.endswith('.txt') == False:
                continue
            split = f.split('_')
            downloadTime = split[1]
            dataStime = split[2]
            if dataStime==stime:    #表示数据是重复数据，不处理
                dealData=False
                addLog('[{0}]数据无需更新-[{1}]-[{2}]'.format(roadCode,f,stime))
                if isOldFile(downloadTime,1*24*60*60):
                    warn(roadCode,1)
            if isOldFile(downloadTime,7*24*60*60):     #删除7天前旧数据
                addLog('[{0}]:[{1}]超过时间被移除'.format(roadCode,f))
                os.remove(os.path.join(txtPath,f))
        return dealData
    addLog('[{0}]数据为空-无法更新'.format(roadCode))
    warn(roadCode,0)
    return False

'''
报警
'''
def warn(roadCode,level):
    if level==0:
        addLog('[{0}]:api获取数据为空'.format(roadCode))
    elif level==1:
        addLog('[{0}]:超过24h数据未更新'.format(roadCode))

#解析api的数据成txt
def parseApiData(txtFile,apiData,roadCode,index,lng,lat):
    '''
        S1 29.7985040000 106.4145540000 2019120121 66 1 0 0 0 71.5 8.8 7 1032.4 26.9 0 0
        点编号 lat lng 预报时间 风向 风速m / s 时雨量mm 时血量mm 云量 % 相对湿度 %
        气温 土温 气压hpa 能见度km 凝冻指数0 - 3 冻雨指数0 - 3
        无参数：td:露点，sw:短波辐射，lw:长波辐射， soilm:土壤湿度， soilw:土壤含水量， stab:大气稳定度
    '''
    line='S{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}\n'
    #12个key
    for data in apiData:
        #stab数据无容纳地方
        #不包含土温和气压，用-999代替
        dataLine = line.format(index, repr(lat), repr(lng), data['time'], data['wd'], data['ws'], data['rain'], data['snow'],
                                  data['cloud'], data['rh'], data['temp'], '-999', '-999', data['vis'], data['freez'], data['ice'])
        txtFile.write(dataLine)
        txtFile.flush()

#通知服务器处理相应文件
def meteoInPut(fileName):
    addLog('开始通知服务器处理txt')
    print(INSERT_FORCAST_DATA + '&txtName=' + fileName)
    result = requests.post(INSERT_FORCAST_DATA + '&txtName=' + fileName)
    if result.status_code==200:
        loads = json.loads(result.text)['msg']
        addLog('处理完成：'+str(loads))
    else:
        addLog('出现异常，未完成')

if __name__=='__main__':
    roadArr = getAllRoad()
    if roadArr is None:
        addLog('无法获取路线信息')
        exit(0)
    for road in roadArr:
        if road['road_code'] in DATA_CONFIG:
            DATA_CONFIG[road['road_code']]['rid']=road['id']
    for roadCfgK in DATA_CONFIG:
        roadCfg=DATA_CONFIG[roadCfgK]
        if roadCfg['update']:
            addLog('[{0}]开始处理api'.format(roadCfgK))
            print(roadCfg)
            forcastArr = getAllForcast(roadCfg['rid'])
            if forcastArr is None:
                addLog('[0] 无法获取预报点数据'.format(roadCfgK))
            else:
                if len(forcastArr)==0:
                    continue
                apiData = getDataFromApi(roadCfg['api'].format(forcastArr[0]['lng'], forcastArr[0]['lat'],roadCfg['plan'][0],roadCfg['nc']), road['road_code'])
                if isUpdated(apiData, roadCfgK)==False:
                    continue
                stime = apiData[0]['time']  # 数据的开始时间
                txtName = TXT_NAME.format(roadCfgK, getTimeStr(), stime)
                txtPath = os.path.join(TXT_PATH.format(roadCfgK), txtName)
                txtFile = open(txtPath, 'a+')
                for index in range(len(forcastArr)):
                    forcast=forcastArr[index]
                    apiData = getDataFromApi(roadCfg['api'].format(forcast['lng'],forcast['lat'],roadCfg['plan'][0],roadCfg['nc']), roadCfgK)
                    parseApiData(txtFile,apiData, roadCfgK, index+1, forcast['lng'],forcast['lat'])
                txtFile.close()
                addLog('文件[{0}]被写入'.format(txtName))
                # meteoInPut(txtName)




